#include "mem.h"
#include "slist.h"

z_slist* z_slist_alloc(void)
{
  z_slist *slist;
  slist = z_new0(z_slist, 1);
  return slist;
}

void z_slist_destroy(z_slist *slist, z_destroy_notify destroy_func) 
{
  z_slist_node *node, *temp;
  
  node = slist->head;
  while (node) {
    temp = node;
    node = node->next;
    if (destroy_func) 
      destroy_func(temp->data);
    zfree(temp);
  }
}

void z_slist_free(z_slist *slist)
{
  zfree(slist);
}

static void internal_z_slist_append(z_slist *slist, void *data, z_slist_node *new_node)
{
  new_node->data = data;
  new_node->next = NULL;
  
  if (slist->tail)
    slist->tail->next = new_node;
  else
    slist->head = new_node;
  slist->tail = new_node;
}

void z_slist_append(z_slist *slist, void *data)
{
  return internal_z_slist_append(slist, data, z_new(z_slist_node, 1));
}

void z_slist_append_chunk(z_slist *slist, void *data, z_mem_chunk *mem_chunk)
{
  return internal_z_slist_append(slist, data, z_mem_chunk_alloc(mem_chunk));
}

static void internal_z_slist_prepend(z_slist *slist, void *data, z_slist_node *new_node)
{
  new_node->data = data;
  new_node->next = slist->head;

  if (!new_node->next)  
    slist->tail = new_node;
  slist->head = new_node;
}

void z_slist_prepend(z_slist *slist, void *data)
{
  return internal_z_slist_prepend(slist, data, z_new(z_slist_node, 1));
}

void z_slist_prepend_chunk(z_slist *slist, void *data, z_mem_chunk *mem_chunk)
{
  return internal_z_slist_prepend(slist, data, z_mem_chunk_alloc(mem_chunk));  
}

#ifdef DEBUGSL
int main() 
{
  z_slist *p = z_slist_alloc();
  
  z_slist_append(p, "aaa");
  z_slist_prepend(p, "bbb");
  z_slist_node *node;
  
  for (node = p->head; node; node = node->next) {
    printf("%s\t", node->data);
  }
  
  z_slist_destroy(p, NULL);
  z_slist_free(p);

  return 0;
}  
#endif
